import 'dart:io';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter/material.dart';
import 'package:extended_image/extended_image.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';

class MediaItem {
    MediaItem({
        required this.id,
        required this.url,
        this.type='image',
        this.cover,
    });

    String id;
    String url;
    String type;
    String? cover;
}

void openMediaPreview({required BuildContext context,required List<MediaItem> mediaItems,int initialIndex=0}){
    Navigator.push(
    context,
        TransparentRoute(
            builder: (context) => MediaPreview(
                mediaItems: mediaItems,
                initialIndex: initialIndex,
            ),
        ),
    );
}

class MediaPreview extends StatefulWidget {
    MediaPreview({
        this.initialIndex = 0,
        required this.mediaItems,
    }) ;

    final int initialIndex;
    final List<MediaItem> mediaItems;

    @override
    State<StatefulWidget> createState() {
        return _MediaPreviewState();
    }
}

class _MediaPreviewState extends State<MediaPreview> with SingleTickerProviderStateMixin{
    GlobalKey<ExtendedImageSlidePageState> slidePagekey =GlobalKey<ExtendedImageSlidePageState>();

    late int currentIndex = widget.initialIndex;
    late TabController tabController ;
    List<VideoPlayerController> videoControllers=[];
    List<VideoItem> videos=[];
    bool showUI=true;

    @override
    void initState() {
        initVideo();
        tabController = TabController(initialIndex: widget.initialIndex,length: widget.mediaItems.length,vsync: this);
        tabController.addListener(() {
            videos.forEach((video) {
                video.controller?.pause();
            });
            setState(() {
                currentIndex=tabController.index;
            });
        });
        super.initState();
    }

    @override
    void dispose(){
        tabController.removeListener(() { });
       	disposeVideo();
        super.dispose();
    }

    initVideo(){
        widget.mediaItems.forEach((element) async{
            if(element.type=='video'){

                VideoItem item=VideoItem(id:element.id,url: element.url);
                VideoPlayerController controller=VideoPlayerController.network(element.url);
                controller.addListener(() {
                    // final bool _isPlaying = controller.value.isPlaying;
                    // LogUtil.v(_isPlaying,tag: "_isPlaying");
                    // if (item.isPlaying != _isPlaying) {
                    //     if(mounted){
                    //         setState(() { item.isPlaying = _isPlaying; });
                    //     }
                    // }
                    // if(controller.value.duration==controller.value.position){
                    //     item.isFinish=true;
                    // }
                });
                controller.initialize().then((_) {
                    if(mounted){
                        setState(() {
                            item.loadedVideo=true;
                        });
                    }
                });
                item.controller=ChewieController(
                    videoPlayerController: controller,
                    showOptions:false,
                    autoPlay: false,
                    looping: false,
                    allowFullScreen: false,
                    allowMuting: false,
                );

                videos.add(item);
				videoControllers.add(controller);
            }
        });
        setState(() {});
    }

	disposeVideo(){
		videoControllers.forEach((c) {
			c.pause();
			c.dispose();
		});
	}

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            backgroundColor: Colors.transparent,
            body: ConstrainedBox(
                constraints: BoxConstraints(
                    minHeight: double.infinity,
                    minWidth:double.infinity
                ),
                child: ExtendedImageSlidePage(
                    key: slidePagekey,
                    child: Stack(
                        children: [
                            GestureDetector(
                                child: TabBarView(controller: tabController,children: [
                                    ...widget.mediaItems.map((item)=>getChildPage(item)).toList()

                                ]),
                                onTap: () {
                                    slidePagekey.currentState!.popPage();
                                    Navigator.pop(context);
                                },
                            ),
                            if(showUI)
                            Positioned(
                                top: MediaQuery.of(context).padding.top,
                                child: Container(
                                    width: MediaQuery.of(context).size.width,
                                    child: Center(child: Text((currentIndex+1).toString()+'/'+widget.mediaItems.length.toString(),style: TextStyle(fontSize: 14.sp,color: Colors.white,fontWeight: FontWeight.w400)),),
                                ),
                            ),
                        ],
                    ),
                    slideAxis: SlideAxis.both,
                    slideType: SlideType.wholePage,
                    onSlidingPage: (state){
                        setState(() {
                            showUI=!state.isSliding;
                        });
                    },
                ),
            ),
        );
    }

    getChildPage(MediaItem item){

        if(item.type=='image'){
            GestureConfig Function(ExtendedImageState) configHandler=(state) {
                return GestureConfig(
                    minScale: 0.9,
                    animationMinScale: 0.7,
                    maxScale: 3.0,
                    animationMaxScale: 3.5,
                    speed: 1.0,
                    inertialSpeed: 100.0,
                    initialScale: 1.0,
                    inPageView: false,
                    initialAlignment: InitialAlignment.center,
                );
            };
            if(item.url.contains('http')){
                return HeroWidget(
                    child: ExtendedImage.network(
                        item.url,
                        enableSlideOutPage: true,
                        mode: ExtendedImageMode.gesture,
                        initGestureConfigHandler: configHandler,
                    ),
                    tag: item.id,
                    slideType: SlideType.onlyImage,
                    slidePagekey: slidePagekey,
                );
            }else{
                return HeroWidget(
                    child: ExtendedImage.file(
                        File(item.url),
                        enableSlideOutPage: true,
                        mode: ExtendedImageMode.gesture,
                        initGestureConfigHandler: configHandler,
                    ),
                    tag: item.id,
                    slideType: SlideType.onlyImage,
                    slidePagekey: slidePagekey,
                );
            }
        }
        if(item.type=='video'){
           VideoItem video=videos.firstWhere((element) => element.id==item.id);
            if(video==null){
                return Container();
            }
            return ExtendedImageSlidePageHandler(
                child: Center(
                    child: Stack(
                        children:[
                            // video.loadedVideo?
                            // AspectRatio(aspectRatio: video.controller!.aspectRatio!,child: Chewie(controller: video.controller!)):Container(
                            //     child:Center(
                            //         child: CircularProgressIndicator(color:Colors.white),
                            //     )
                            // ),
                            video.loadedVideo?Chewie(controller: video.controller!):Center(
                                child:SizedBox(
                                    width: 20.w,
                                    height: 20.w,
                                    child: CircularProgressIndicator(color:Colors.white,strokeWidth: 2),
                                )
                            )

                            // Positioned.fill(
                            //     child: GestureDetector(
                            //         behavior:HitTestBehavior.translucent,
                            //         onTap:(){
                            //             // if(video.controller?.value.state==FijkState.prepared){
                            //             //     video.controller?.pause();
                            //             // }else{
                            //             //     if(video.isFinish){
                            //             //         video.controller?.seekTo(Duration(milliseconds:0));
                            //             //         video.isFinish=false;
                            //             //     }
                            //             //     video.controller?.play();
                            //             // }
                            //         },
                            //         child: Container(
                            //             child: Center(
                            //                 child:!video.isPlaying?Icon(Icons.play_arrow,size:40,color: Colors.white):Container(),
                            //             ),
                            //         ),
                            //     ),
                            // )
                        ]
                    )
                ),

                ///make hero better when slide out
                heroBuilderForSlidingPage: (Widget result) {

                    return Hero(
                        tag: item.id,
                        child: result,
                        flightShuttleBuilder: (BuildContext flightContext,
                            Animation<double> animation,
                            HeroFlightDirection flightDirection,
                            BuildContext fromHeroContext,
                            BuildContext toHeroContext) {
                        final Hero hero =
                            (flightDirection == HeroFlightDirection.pop
                                ? fromHeroContext.widget
                                : toHeroContext.widget) as Hero;

                        return hero.child;
                        },
                    );
                },
            );
        }
    }
}



class VideoItem {
    VideoItem({
        required this.id,
        required this.url,
        this.controller,
        this.isPlaying=false,
        this.isFinish=false,
        this.loadedVideo=false,
    });

    final String id;
    final String url;
    ChewieController? controller;
    bool isPlaying=false;
    bool isFinish=false;
    bool loadedVideo=false;
}

/// 透明渐现路由
class TransparentRoute extends PageRoute<void> {
  TransparentRoute({
    required this.builder,
    RouteSettings? settings,
  })  : assert(builder != null),
        super(settings: settings, fullscreenDialog: false);

  final WidgetBuilder builder;

  @override
  bool get opaque => false;

  @override
  Color? get barrierColor => null;

  @override
  String? get barrierLabel => null;

  @override
  bool get maintainState => true;

  @override
  bool get fullscreenDialog => true;

  @override
  Duration get transitionDuration => Duration(milliseconds: 350);

  @override
  Widget buildPage(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation) {
    final result = builder(context);
    return FadeTransition(
      opacity: Tween<double>(begin: 0, end: 1).animate(animation),
      child: Semantics(
        scopesRoute: true,
        explicitChildNodes: true,
        child: result,
      ),
    );
  }
}

class HeroWidget extends StatefulWidget {
  const HeroWidget({
    required this.child,
    required this.tag,
    required this.slidePagekey,
    this.slideType = SlideType.onlyImage,
  });
  final Widget child;
  final SlideType slideType;
  final Object tag;
  final GlobalKey<ExtendedImageSlidePageState> slidePagekey;
  @override
  _HeroWidgetState createState() => _HeroWidgetState();
}

class _HeroWidgetState extends State<HeroWidget> {
  late RectTween _rectTween;
  @override
  Widget build(BuildContext context) {
    return Hero(
      tag: widget.tag,
      createRectTween: (Rect? begin, Rect? end) {
        _rectTween = RectTween(begin: begin, end: end);
        return _rectTween;
      },
      // make hero better when slide out
      flightShuttleBuilder: (BuildContext flightContext,
          Animation<double> animation,
          HeroFlightDirection flightDirection,
          BuildContext fromHeroContext,
          BuildContext toHeroContext) {
        // make hero more smoothly
        final Hero hero = (flightDirection == HeroFlightDirection.pop
            ? fromHeroContext.widget
            : toHeroContext.widget) as Hero;
        if (flightDirection == HeroFlightDirection.pop) {
          final bool fixTransform = widget.slideType == SlideType.onlyImage &&
              (widget.slidePagekey.currentState!.offset != Offset.zero ||
                  widget.slidePagekey.currentState!.scale != 1.0);

          final Widget toHeroWidget = (toHeroContext.widget as Hero).child;
          return AnimatedBuilder(
            animation: animation,
            builder: (BuildContext buildContext, Widget? child) {
              Widget animatedBuilderChild = hero.child;

              // make hero more smoothly
              animatedBuilderChild = Stack(
                clipBehavior: Clip.antiAlias,
                alignment: Alignment.center,
                children: <Widget>[
                  Opacity(
                    opacity: 1 - animation.value,
                    child: UnconstrainedBox(
                      child: SizedBox(
                        width: _rectTween.begin!.width,
                        height: _rectTween.begin!.height,
                        child: toHeroWidget,
                      ),
                    ),
                  ),
                  Opacity(
                    opacity: animation.value,
                    child: animatedBuilderChild,
                  )
                ],
              );

              // fix transform when slide out
              if (fixTransform) {
                final Tween<Offset> offsetTween = Tween<Offset>(
                    begin: Offset.zero,
                    end: widget.slidePagekey.currentState!.offset);

                final Tween<double> scaleTween = Tween<double>(
                    begin: 1.0, end: widget.slidePagekey.currentState!.scale);
                animatedBuilderChild = Transform.translate(
                  offset: offsetTween.evaluate(animation),
                  child: Transform.scale(
                    scale: scaleTween.evaluate(animation),
                    child: animatedBuilderChild,
                  ),
                );
              }

              return animatedBuilderChild;
            },
          );
        }
        return hero.child;
      },
      child: widget.child,
    );
  }
}
